package cate.game.activity.firstpay;

import cate.common.table.activity.firstpay.common.SuperFirstPayCommonRow;
import cate.common.table.activity.firstpay.item.SuperFirstPayItemRow;
import cate.common.table.d.GDNotice;
import cate.common.table.d.GDObj;
import cate.common.table.d.GDOperation;
import cate.common.util.GameResult;
import cate.game.chat.ChatContentParam;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import cate.game.res.MixResItem;
import cate.game.role.Role;
import cate.game.role.RoleDependent;
import cate.game.role.bag.equip.Equip;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.beans.Transient;
import java.util.*;

@NoteClass(value = "累计充值-单档信息")
public class SuperFirstPayLevel extends RoleDependent {
    @NoteField(value = "是否激活")
    public boolean active;
    @NoteField(value = "是否结束")
    public boolean over;
    @NoteField(value = "档位")
    public int level;
    @NoteField(value = "登录天数")
    public int loginDays;
    @NoteField(value = "领取状态")
    public Map<Integer, Boolean> gotMap;

    public SuperFirstPayLevel() {
    }

    public SuperFirstPayLevel(int level) {
        this.level = level;
    }

    /**
     * 初始化档位信息
     *
     * @param role 玩家
     */
    public void initialize(Role role) {
        super.initialize(role);
        if (gotMap == null) {
            gotMap = new HashMap<>();
        }
        dataCheck();
    }

    /**
     * 数据兼容检测
     */
    public void dataCheck() {
        // 删除多余项
        gotMap.entrySet().removeIf(entry -> role.getGame().table.firstPay.item.get(entry.getKey()) == null);
        // 添加新增项
        for (SuperFirstPayItemRow configRow : role.getGame().table.firstPay.item.getList()) {
            if (configRow.level != level) {
                continue;
            }
            if (gotMap.containsKey(configRow.id)) {
                continue;
            }
            gotMap.put(configRow.id, false);
        }
        // 检测重开
        if (over && !checkOver()) {
            over = false;
        }
    }

    /**
     * 获取超值首充基础配置
     *
     * @return 配置条目
     */
    @JsonIgnore
    public SuperFirstPayCommonRow getCommonConfigRow() {
        return role.getGame().table.firstPay.common.get(level);
    }

    /**
     * 充值时触发
     */
    public void onPay() {
        if (active || over) {
            return;
        }
        if (role.getPay().paySum >= getCommonConfigRow().needPayNum) {
            active = true;
            loginDays++;
        }
    }

    /**
     * 检测是否结束
     */
    @JsonIgnore
    public boolean checkOver() {
        return gotMap.values().stream().anyMatch(v -> !v);
    }

    @Override
    public void onDaySpan(boolean silence) {
        super.onDaySpan(silence);
        if (active && !over) {
            loginDays++;
        }
    }

    /**
     * 领取奖励
     *
     * @param configId 奖励配置ID
     * @return 领取结果 无携带数据
     */
    @JsonIgnore
    @Transient
    public GameResult<Void> getReward(int configId) {
        GameResult<Void> r = new GameResult<>();
        if (!active) {
            return r.fail("活动未开启");
        }
        if (over) {
            return r.fail("活动已结束");
        }
        if (!gotMap.containsKey(configId)) {
            return r.fail("未找到奖励项");
        }
        if (gotMap.get(configId)) {
            return r.fail("奖励已领取");
        }
        SuperFirstPayItemRow configRow = role.getGame().table.firstPay.item.get(configId);
        if (configRow == null || configRow.level != level) {
            return r.fail("未找到奖励项");
        }
        if (loginDays < configRow.day) {
            return r.fail("未达到天数");
        }
        MixRes mixRes = new MixRes(configRow.rewardStr);
        if (mixRes.isEmpty()) {
            return r.fail("奖励配置缺失");
        }
        if (configRow.campMarks.size() > 0) {
            List<MixResItem> equipItems = new ArrayList<>();
            Iterator<MixResItem> iter = mixRes.items.iterator();
            int index = 0;
            while (iter.hasNext()) {
                index++;
                MixResItem mixResItem = iter.next();
                if (mixResItem.type == GDObj.Type.EQUIP && configRow.campMarks.containsKey(index)) {
                    byte camp = configRow.campMarks.get(index);
                    if (role.getGame().table.equip.base.get(mixResItem.tid) != null) {
                        for (int i = 0; i < mixResItem.num; i++) {
                            Equip equip = new Equip(role, mixResItem.tid, 1);
                            equip.campMark = camp;
                            equipItems.add(new MixResItem(equip));
                        }
                    }
                    iter.remove();
                }
            }
            if (equipItems.size() > 0) {
                mixRes.items.addAll(equipItems);
            }
        }
        if (level == 1 && gotMap.values().stream().noneMatch(v -> v)) {
            lamp();
        }
        // 记录领取状态
        gotMap.put(configId, true);
        new MixResAdder().setRes(mixRes)
                .setSendMailWhenFull(true)
                .setDialogReward(true)
                .setOperation(GDOperation.ACT_SUPER_FIRST_PAY)
                .setOperationSub(configId)
                .exe(role);
        return r.success();
    }

    private void lamp() {
        List<ChatContentParam> params = new ArrayList<>();
        params.add(ChatContentParam.c(role.getBase().name));
        role.getGame().notice.lampOnline(role, GDNotice.TextId.FIRST_PAY, params);
    }

    /**
     * 领取奖励
     *
     * @return 领取结果 无携带数据
     */
    @JsonIgnore
    @Transient
    public GameResult<Void> getRewardByLevel() {
        GameResult<Void> r = new GameResult<>();
        if (!active) {
            return r.fail("活动未开启");
        }
        if (over) {
            return r.fail("活动已结束");
        }
        MixRes mixRes = new MixRes();
        for (Integer configId : gotMap.keySet()) {
            SuperFirstPayItemRow configRow = role.getGame().table.firstPay.item.get(configId);
            if (configRow == null || configRow.level != level) {
                continue;
            }
            if (loginDays < configRow.day) {
                continue;
            }
            if (gotMap.get(configId)) {
                continue;
            }
            MixRes res = new MixRes(configRow.rewardStr);
            if (res.isEmpty()) {
                continue;
            }
            if (configRow.campMarks.size() > 0) {
                List<MixResItem> equipItems = new ArrayList<>();
                Iterator<MixResItem> iter = res.items.iterator();
                int index = 0;
                while (iter.hasNext()) {
                    index++;
                    MixResItem mixResItem = iter.next();
                    if (mixResItem.type == GDObj.Type.EQUIP && configRow.campMarks.containsKey(index)) {
                        byte camp = configRow.campMarks.get(index);
                        if (role.getGame().table.equip.base.get(mixResItem.tid) != null) {
                            for (int i = 0; i < mixResItem.num; i++) {
                                Equip equip = new Equip(role, mixResItem.tid, 1);
                                equip.campMark = camp;
                                equipItems.add(new MixResItem(equip));
                            }
                        }
                        iter.remove();
                    }
                }
                if (equipItems.size() > 0) {
                    res.items.addAll(equipItems);
                }
            }
            if (level == 1 && gotMap.values().stream().noneMatch(v -> v)) {
                lamp();
            }
            if (!res.isEmpty()) {
                mixRes.addList(res);
                // 记录领取状态
                gotMap.put(configId, true);
            }
        }
        if (mixRes.isEmpty()) {
            return r.fail("无可领取的奖励");
        }

        new MixResAdder().setRes(mixRes)
                .setSendMailWhenFull(true)
                .setDialogReward(true)
                .setOperation(GDOperation.ACT_SUPER_FIRST_PAY)
                .exe(role);
        return r.success();
    }
}
